﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using YArchitech.LIB;
using YArchitech.Revit;
using SystemDiagramNew.TypeDefinition;
using SystemDiagramNew.Utils;

namespace SystemDiagramNew
{
	public class SetElevation
	{
		public SetElevation(ExternalCommandData data, Reference reference)
		{
			this.revitData = data;
			this.referenceObj = reference;
		}

		public bool Execute(bool underPipe, int precisionIndex, bool isCustom, bool isDelete, string prefixText, string customText, ElevationLabelLocation location)
		{
			bool result = false;
			if (this.referenceObj != null)
			{
				try
				{
					Pipe itsPipe = this.GetItsPipe();
					if (itsPipe != null)
					{
						double num = itsPipe.get_Parameter(BuiltInParameter.RBS_START_OFFSET_PARAM).AsDouble();
						double num2 = itsPipe.get_Parameter(BuiltInParameter.RBS_END_OFFSET_PARAM).AsDouble();
						num = AssistFunc.feetToMM(num) / 1000.0;
						num2 = AssistFunc.feetToMM(num2) / 1000.0;
						double num3 = Convert.ToDouble(customText);
						int precision = precisionIndex + SetPipeElevation.offset;
						XYZ globalPoint = this.referenceObj.GlobalPoint;
						Document document = this.revitData.Application.ActiveUIDocument.Document;
						Element element = document.GetElement(this.referenceObj);
						Line curve = (element as DetailLine).GeometryCurve as Line;
						XYZ hyendPoint = curve.GetEndPoint(0);
						XYZ hyendPoint2 = curve.GetEndPoint(1);
						if (isDelete)
						{
							this.DeleteDetailGroups(document, element, "标高详图组");
						}
						string elevation = string.Empty;
						double elevation2;
						if (isCustom)
						{
							elevation2 = num3;
						}
						else if (location == ElevationLabelLocation.InnerPipe)
						{
							elevation2 = num;
							if (!Geometry.IsEqual(num, num2))
							{
								double length = (hyendPoint2 - hyendPoint).GetLength();
								double length2 = (globalPoint - hyendPoint).GetLength();
								elevation2 = num + (num2 - num) * length2 / length;
							}
						}
						else
						{
							double num4 = globalPoint.DistanceTo(hyendPoint);
							double num5 = hyendPoint.DistanceTo(hyendPoint2);
							if (num4 > num5)
							{
								elevation2 = num2;
							}
							else
							{
								elevation2 = num;
							}
						}
						elevation = this.GetElevationText(elevation2, precision, prefixText);
						this.MarkElevation(globalPoint, hyendPoint, hyendPoint2, underPipe, elevation, location);
						result = true;
					}
				}
				catch (Exception ex)
				{
					ex.ToString();
				}
			}
			return result;
		}

		protected void MarkElevation(XYZ ptSelect, XYZ ptStart, XYZ ptEnd, bool underPipe, string elevation, ElevationLabelLocation location)
		{
			TextNoteType type = this.revitData.CreateTextNoteType();
			int scale = this.revitData.Application.ActiveUIDocument.ActiveView.Scale;
			CurveArray curveArray = new CurveArray();
			XYZ xyz = (ptEnd - ptStart).Normalize();
			TextNote textNote = null;
			if (location == ElevationLabelLocation.InnerPipe)
			{
				curveArray = this.DrawElevation(ptSelect, xyz, elevation, 1.0, type, scale, underPipe, false, false, ref textNote);
			}
			else
			{
				XYZ ptInsert = ptEnd;
				double length = (ptEnd - ptStart).GetLength();
				if (Geometry.LessThan((ptSelect - ptStart).GetLength(), length / 2.0))
				{
					ptInsert = ptStart;
					xyz = -xyz;
				}
				curveArray = this.DrawElevation(ptInsert, xyz, elevation, 1.0, type, scale, underPipe, true, true, ref textNote);
			}
			Autodesk.Revit.DB.View activeView = this.revitData.Application.ActiveUIDocument.ActiveView;
			new DetailCurveArray();
			try
			{
				Document document = this.revitData.Application.ActiveUIDocument.Document;
				DetailCurveArray detailCurveArray = document.Create.NewDetailCurveArray(activeView, curveArray);
				ElementSet elementSet = new ElementSet();
				elementSet.Insert(textNote);
				foreach (object obj in detailCurveArray)
				{
					DetailCurve detailCurve = (DetailCurve)obj;
					elementSet.Insert(detailCurve);
				}
				Group group = document.CreatYJKGroup(elementSet);
				Element element = document.GetElement(this.referenceObj);
				string text = ExtensibleStorageManager.ReadDetailGroupsInfo(element);
				if (text != null)
				{
					if (text != string.Empty)
					{
						text += "*";
					}
					text += group.Id.ToString();
					ExtensibleStorageManager.WriteDetailGroupsInfo(element, text);
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
		}

		protected CurveArray DrawElevation(XYZ ptInsert, XYZ direction, string strElevation, double legendScale, TextNoteType type, int viewScale, bool underPipe, bool offset, bool drawBottomLine, ref TextNote textnote)
		{
			CurveArray curveArray = new CurveArray();
			double num = AssistFunc.mmToFeet(100.0) * legendScale;
			double num2 = num * 2.0;
			XYZ xyz = ptInsert - direction * (num2 / 2.0);
			XYZ xyz2 = ptInsert + direction * (num2 / 2.0);
			if (offset)
			{
				xyz = ptInsert + direction * num;
				xyz2 = ptInsert + direction * (num + num2);
			}
			XYZ ptStart = xyz + (xyz2 - xyz) / 2.0;
			if (drawBottomLine)
			{
				Line line = this.CreateLine(xyz, xyz2);
				if (null != line)
				{
					curveArray.Append(line);
				}
			}
			double angle = Geometry.getAngle(XYZ.Zero, direction);
			double num3 = angle;
			XYZ xyz3;
			if (Geometry.GreaterThan(angle, Math.PI*.5) && Geometry.Lessthan_Or_Equal(angle, 4.71238898038469))
			{
				xyz3 = Geometry.RotateTo(direction, -Math.PI*.5, XYZ.BasisZ);
				num3 = Geometry.formatAngle(num3 - Math.PI);
			}
			else
			{
				xyz3 = Geometry.RotateTo(direction, Math.PI*.5, XYZ.BasisZ);
			}
			if (!underPipe)
			{
				xyz3 = -xyz3;
			}
			XYZ xyz4 = xyz + xyz3 * num2 / 2.0;
			XYZ xyz5 = xyz2 + xyz3 * num2 / 2.0;
			XYZ xyz6 = xyz4 + direction * (num2 + (double)strElevation.Length * SetElevation.TextWidth * (double)viewScale * 0.6);
			Line line2 = this.CreateLine(ptStart, xyz4);
			if (line2 != null)
			{
				curveArray.Append(line2);
			}
			Line line3 = this.CreateLine(ptStart, xyz5);
			if (line3 != null)
			{
				curveArray.Append(line3);
			}
			Line line4 = this.CreateLine(xyz4, xyz6);
			if (line4 != null)
			{
				curveArray.Append(line4);
			}
			XYZ pt = xyz5 + (xyz6 - xyz5) / 2.0;
			XYZ xyz7 = xyz3.Normalize();
			XYZ ptTextCenter = pt.GetXY() + xyz7 * (0.5 * SetElevation.TextHeight + SetElevation.TextOffsetLine + UnifiedModified.GetSystemDiagramDrawSize()[1]) * (double)viewScale;
			Autodesk.Revit.DB.View activeView = this.revitData.Application.ActiveUIDocument.ActiveView;
			textnote = activeView.CreateTextNote(strElevation, ptTextCenter, this.GetVector(num3));
			return curveArray;
		}

		public Pipe GetItsPipe()
		{
			Pipe result = null;
			Document document = this.revitData.Application.ActiveUIDocument.Document;
			if (this.referenceObj != null)
			{
				Element element = document.GetElement(this.referenceObj);
				if (element != null)
				{
					ElementId modelId = element.GetModelId();
					if (modelId != ElementId.InvalidElementId)
					{
						result = (document.GetElement(modelId) as Pipe);
					}
				}
			}
			return result;
		}

		protected string DoublePrecision(double dVal, int nDotNum = 2)
		{
			string result = dVal.ToString();
			try
			{
				string format = "f" + nDotNum.ToString();
				result = dVal.ToString(format);
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
			return result;
		}

		protected XYZ GetVector(double angle)
		{
			return new XYZ(Math.Cos(angle), Math.Sin(angle), 0.0);
		}

		protected Line CreateLine(XYZ ptStart, XYZ ptEnd)
		{
			Line result;
			try
			{
				result = Line.CreateBound(ptStart, ptEnd);
			}
			catch (Exception ex)
			{
				ex.ToString();
				ex.ToString();
				result = null;
			}
			return result;
		}

		protected string GetElevationText(double elevation, int precision, string prefix)
		{
			string result = string.Empty;
			try
			{
				string str = this.DoublePrecision(elevation, precision);
				result = prefix + str;
			}
			catch (Exception ex)
			{
				ex.ToString();
			}
			return result;
		}

		protected void SetDetailGroupsParameter()
		{
			string pathName = Path.Combine(Product.DataLocation, "HYShared Parameters.txt");
			YJKRevitTools.SetInstanceParameter(this.revitData.Application, pathName, "图纸", "标高详图组", BuiltInCategory.OST_Lines, true);
		}

		protected void DeleteDetailGroups(Autodesk.Revit.DB.Document doc, Element elem, string paraName)
		{
			string text = ExtensibleStorageManager.ReadDetailGroupsInfo(elem);
			List<Element> elementByCategory = YJKElementFilter.GetElementByCategory(doc, BuiltInCategory.OST_IOSDetailGroups);
			if (text != null)
			{
				List<string> list = text.Split(new char[]
				{
					'*'
				}).ToList<string>();
				foreach (Element element in elementByCategory)
				{
					if (list.Contains(element.Id.ToString()))
					{
						doc.DeleteElement(element);
					}
				}
				ExtensibleStorageManager.WriteDetailGroupsInfo(elem, string.Empty);
			}
		}

		protected static readonly double TextHeight = 2.5.MMtoFeet();

		protected static readonly double TextWidth = 2.5.MMtoFeet() * 0.7;

		protected static readonly double TextOffsetLine = AssistFunc.mmToFeet(1.0);

		public ExternalCommandData revitData;

		public Reference referenceObj;

		public Pipe pipe;
	}
}
